import cv2  # 导入opencv库，用于访问摄像头
import platform  # 导入platform库，用于获取操作系统信息
import subprocess
import json


def detect_cameras():
    """
    检测并返回所有已连接的摄像头及其名称（如果可用）。

    :return: 一个列表，包含元组(index, camera_name)，其中index是摄像头的索引，camera_name是摄像头的名称。
    """
    camera_list = []  # 初始化一个空列表，用于存储检测到的摄像头信息
    index = 0  # 从索引0开始检测摄像头

    # 根据操作系统选择合适的OpenCV后端
    system = platform.system()
    if system == "Windows":
        backend = cv2.CAP_DSHOW
    elif system == "Darwin":  # macOS
        backend = cv2.CAP_AVFOUNDATION
    else:  # Linux和其他系统
        backend = cv2.CAP_V4L2

    while True:  # 无限循环，直到没有更多的摄像头可以检测
        cap = cv2.VideoCapture(index, backend)  # 尝试打开当前索引的摄像头
        if not cap.isOpened():  # 如果当前索引的摄像头无法打开
            break  # 退出循环
        else:  # 如果摄像头成功打开
            camera_name = get_camera_name(index, system)  # 获取摄像头名称
            camera_list.append((index, camera_name))  # 将摄像头索引和名称添加到列表中
            cap.release()  # 释放摄像头资源
        index += 1  # 索引递增，准备检测下一个摄像头

    return camera_list  # 返回检测到的所有摄像头的列表


def get_camera_name(index, system):
    """
    根据操作系统获取摄像头名称
    
    :param index: 摄像头索引
    :param system: 操作系统类型
    :return: 摄像头名称
    """
    try:
        if system == "Windows":
            return get_windows_camera_name(index)
        elif system == "Darwin":  # macOS
            return get_macos_camera_name(index)
        elif system == "Linux":
            return get_linux_camera_name(index)
        else:
            return f"摄像头 {index}"
    except Exception:
        return f"摄像头 {index}"


def get_windows_camera_name(index):
    """获取Windows系统摄像头名称"""
    try:
        import win32com.client
        wmi = win32com.client.Dispatch("WbemScripting.SWbemLocator")
        wbem_service = wmi.ConnectServer(".", r"root\cimv2")
        query = f"SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%Camera%' OR Description LIKE '%Camera%'"
        for item in wbem_service.ExecQuery(query):
            if item.Description:
                return item.Description
        return f"摄像头 {index}"
    except ImportError:
        return f"摄像头 {index}"


def get_macos_camera_name(index):
    """获取macOS系统摄像头名称"""
    try:
        # 使用system_profiler获取摄像头信息
        result = subprocess.run([
            'system_profiler', 'SPCameraDataType', '-json'
        ], capture_output=True, text=True, timeout=5)
        
        if result.returncode == 0:
            camera_data = json.loads(result.stdout)
            cameras = camera_data.get('SPCameraDataType', [])
            if index < len(cameras):
                return cameras[index].get('_name', f"摄像头 {index}")
    except (subprocess.TimeoutExpired, json.JSONDecodeError, IndexError):
        pass
    return f"摄像头 {index}"


def get_linux_camera_name(index):
    """获取Linux系统摄像头名称"""
    try:
        # 尝试使用v4l2-ctl获取设备信息
        result = subprocess.run([
            'v4l2-ctl', '--device', f'/dev/video{index}', '--info'
        ], capture_output=True, text=True, timeout=3)
        
        if result.returncode == 0:
            for line in result.stdout.split('\n'):
                if 'Card type' in line:
                    return line.split(':')[1].strip()
    except (subprocess.TimeoutExpired, FileNotFoundError, IndexError):
        pass
    return f"摄像头 {index}"
